'use strict'
let routes = require('./route')
let sceneMgr = require('./sceneMgr')
let nodeMgr = require('./nodeMgr')
let util = require('util')
let rc4a = require('./rc4a.js')

//会话类(用户连接类)
class Session {
  constructor(sId, socket) {
    this.id = sId
    this.pId = null //登陆的角色id
    this.sceneId = null //角色所在的场景id
    this.socket = socket
    this.heartbeat = 0 //心跳
    let self = this
    socket.on('message', function(data) {
      try {
        if (!Buffer.isBuffer(data) || data.length <= 4) {
          return
        }
        data = rc4a.decodeBuffer(data)
        data = JSON.parse(data)
        if (!util.isObject(data.msg)) {
          data.msg = {}
        }
      } catch (e) {
        return
      }
      Log(data)
      let method
      if (self.pId) {
        method = routes.getLogin(data.route)
        if (method) {
          method(self, data.msg, function(result) {
            if (typeof result === 'number') {
              result = {
                error: result
              }
            }
            self.send(result, data.reqId)
          })
          return
        }
        let nodeName = routes.getNodeName(data.route)
        if (nodeName) {
          nodeMgr.nodesName[nodeName].send(self.pId, data.route, data.msg, function(result) {
            self.send(result, data.reqId)
          })
        }
      } else {
        method = routes.getNotLogin(data.route)
        if (method) {
          method(self, data.msg, function(result) {
            if (typeof result === 'number') {
              result = {
                error: result
              }
            }
            self.send(result, data.reqId)
          })
        }
      }
    })

    socket.on('close', function(data) {
      if (self.pId) {
        //保存用户信息
        let node = nodeMgr.nodesName['node1']
        node.send(self.pId, 'savePlayerAndClose', '', function(res) {})
        let sceneId = self.sceneId
        sceneMgr.getSceneSerById(sceneId).dropClient(self.id) //离开当前场景
      }
      playerSessionMgr.delSessionBySid(self.id)
    })

    socket.on('error', function(data) {
      this.emit('close')
    })
  }

  //发送消息
  send(msg, reqId) {
    var sendData = {}
    if (reqId) {
      sendData['reqId'] = reqId
    }
    sendData['msg'] = msg
    sendData = JSON.stringify(sendData)
    this.socket.send(rc4a.encodeStr(sendData))
  }

  //发送消息
  push(msg, route) {
    var sendData = {
      msg: msg,
      route: route
    }
    sendData = JSON.stringify(sendData)
    this.socket.send(rc4a.encodeStr(sendData))
  }

  close() {
    this.socket.close()
  }
}


//会话管理类(用户连接管理类)
class PlayerSessionMgr {
  constructor() {
    this.sessions = {} //保存socket.id对应的session
    this.sessionsPid = {} //保存pId对应的session
  }

  create(sId, socket) {
    var session = new Session(sId, socket)
    this.sessions[sId] = session
    return session
  }

  get(sId) {
    return this.sessions[sId]
  }

  getByPid(pId) {
    return this.sessionsPid[pId]
  }

  getPIdBysId(sId) {
    return this.sessions[sId].pId
  }

  bind(sId, pId) {
    if (this.sessionsPid[pId]) {
      if (this.sessionsPid[pId].id === sId) {
        //原来的用户重新登陆
        return 0
      }
      //不允许同一账号登陆多个客户端
      //服务器先断开原来的客户端
      //保存用户信息
      let sceneId = this.sessionsPid[pId].sceneId
      sceneMgr.getSceneSerById(sceneId).dropClient(this.sessionsPid[pId].id)
      this.sessionsPid[pId].pId = null
      this.sessionsPid[pId].socket.close()
      this.delSession(this.sessionsPid[pId])
    }

    let session = this.sessions[sId]
    if(!session){
      return -1
    }
    session.pId = pId
    this.sessionsPid[pId] = session
    return session
  }

  delSession(session) {
    delete this.sessions[this.sId]
    delete this.sessionsPid[this.pId]
  }

  delSessionBySid(sId) {
    let session = this.sessions[sId]
    if (session) {
      delete this.sessions[sId]
      if (session.pId) {
        delete this.sessionsPid[session.pId]
      }
    }
  }

  //推送消息到玩家
  pushMsgToPlayer(pId, msg, route) {
    let session = this.sessionsPid[pId]
    if (session) {
      session.push(msg, route)
    }
  }

  //推送消息到当前场景
  pushMsgsToScene(sceneId, msg, route) {
    let clients = sceneMgr.getSceneSerById(sceneId).getClients()
    for (let sId of clients) {
      let session = this.sessions[sId]
      if (session)
        session.push(msg, route)
    }
  }
}

let playerSessionMgr = new PlayerSessionMgr()
module.exports = playerSessionMgr

setInterval(function() { //每隔5分钟做一次心跳,4次没有处理的就断开连接
  var sessions = playerSessionMgr.sessions
  for (var i in sessions) {
    var session = sessions[i]
    if (session.heartbeat < 4) {
      session.heartbeat += 1
    } else { //断开连接
      session.close()
    }
  }
}, 300000)
